package com.kellycheung.chicken_go_go;

import com.kellycheung.chicken_go_go.GTouchPoint.TouchAction;

import android.view.MotionEvent;

public class ClickableObj extends GameObject {
	protected static final int I_CLICK_DELAY = 10;
	
	protected ButtonFunction cBtnClickAct;
	protected ButtonFunction cBtnPressAct;
	protected ButtonFunction cBtnReleaseAct;
	
	protected int iAllowClick;
	protected int iClickCnt;
	protected int iPressCnt;
	protected int iClickDelayCnt;
	protected int iTouchId;
	protected int iIsTouching;
	protected boolean bClickAndRelease;
	
	public ClickableObj( GameScene p_gsScene , int p_iZOrder , GOAnchor p_goa ) {
		this( p_gsScene , p_iZOrder , p_goa , 0f , 0f );
	}
	
	public ClickableObj( GameScene p_gsScene , int p_iZOrder , GOAnchor p_goa , float p_fX , float p_fY ) {
		super( p_gsScene , p_iZOrder , p_goa , p_fX , p_fY );
		
		try {
			this.resetValue();
			this.iAllowClick = 1;
			this.iClickDelayCnt = 0;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj(GameScene,int,GOAnchor,float,float)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	@Override
	public void destroy() {
		try {
			this.cBtnClickAct = null;
			this.cBtnPressAct = null;
			this.cBtnReleaseAct = null;
			
			super.destroy();
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.destroy" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void click( GCoordinate p_gc ) {
		try {
			if ( this.isAllowRun() ) {
				this.iIsTouching = ClickableObj.I_CLICK_DELAY;
				
				if ( this.isTouching( p_gc ) ) {
					if ( this.iClickCnt < this.iAllowClick ) {
						if ( this.iClickDelayCnt == 0 ) {
							if ( this.cBtnClickAct != null ) {
								this.cBtnClickAct.call();
							}
							
							if ( this.bClickAndRelease ) {
								this.release();
							}
							else {
								this.iClickCnt++;
								this.iClickDelayCnt = ClickableObj.I_CLICK_DELAY;
							}
						}
					}
				}
				else {
					this.release();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.click" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public boolean isTouching( GCoordinate p_gc ) {
		try {
			if ( this.isAllowRun() ) {
				this.setBound();
				
				return this.grBound.isInside( p_gc );
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.isTouching" );
			GameUtil.ErrorHandler( this , p_e );
		}
		
		return false;
	}
	
	
	@Override
	public void preGameLoopLogic() {
		try {
			if ( this.iClickDelayCnt > 0 ) {
				this.iClickDelayCnt--;
			}
			
			if ( this.iClickDelayCnt == 0 && this.iClickCnt > 0 ) {
				this.iClickCnt--;
			}
			
			if ( this.iClickCnt == 0 && this.iIsTouching > 0 ) {
				this.iIsTouching--;
				
				if ( this.iIsTouching == 0 ) {
					this.resetValue();
				}
			}
			
			super.preGameLoopLogic();
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.preGameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	

	public void press( GCoordinate p_gc ) {
		try {
			if ( this.isAllowRun() ) {
				this.iIsTouching = ClickableObj.I_CLICK_DELAY;
				
				if ( this.isTouching( p_gc ) ) {
					if ( this.cBtnPressAct != null ) {
						this.cBtnPressAct.call();
					}
					this.iPressCnt++;
				}
				else {
					this.release();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.press" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void processInput( TouchAction p_ta ) {
		// TODO Auto-generated method stub
		try {
			if ( this.isAllowRun() ) {
				if ( this.iTouchId == -1 ) {
					if ( this.isTouching( p_ta.gcThis ) ) {
						switch ( p_ta.iAction ) {
						case MotionEvent.ACTION_DOWN:
							if ( p_ta.updateObjRef( this ) ) {
								this.iTouchId = p_ta.iTouchId;
							}
							break;
						
						case MotionEvent.ACTION_POINTER_DOWN:
							if ( p_ta.updateObjRef( this ) ) {
								this.iTouchId = p_ta.iTouchId;
							}							
							break;
						}
					}
				}
				
				if ( this.iTouchId == p_ta.iTouchId ) {
					switch ( p_ta.iAction ) {
					case MotionEvent.ACTION_DOWN:
						this.click( p_ta.gcThis );
						this.press( p_ta.gcThis );
						break;
					
					case MotionEvent.ACTION_POINTER_DOWN:
						this.click( p_ta.gcThis );
						this.press( p_ta.gcThis );
						break;
					
					case MotionEvent.ACTION_MOVE:
						this.press( p_ta.gcThis );
						break;
						
					case MotionEvent.ACTION_POINTER_UP:
						this.release();
						break;
					
					case MotionEvent.ACTION_UP:
						this.release();
						break;
					}
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.processInput" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void release() {
		try {
			if ( this.isAllowRun() ) {
				if ( this.cBtnReleaseAct != null ) {
					this.cBtnReleaseAct.call();
				}
				
				this.resetValue();
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.release" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void resetValue() {
		try {
			this.iPressCnt = 0;
			this.iClickCnt = 0;
			this.iTouchId = -1;
			this.iIsTouching = 0;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.resetValue" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public <T> void setBtnClickAct( ButtonFunction p_c ) {
		try {
			this.setBtnClickAct( p_c , true );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.setBtnClickAct(ButtonFunction)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public <T> void setBtnClickAct( ButtonFunction p_c , boolean p_bClickAndRelease ) {
		try {
			this.cBtnClickAct = p_c;
			this.bClickAndRelease = p_bClickAndRelease;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.setBtnClickAct(ButtonFunction,boolean)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public <T> void setBtnPressAct( ButtonFunction p_c ) {
		try {
			this.cBtnPressAct = p_c;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.setBtnPressAct" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public <T> void setBtnReleaseAct( ButtonFunction p_c ) {
		try {
			this.cBtnReleaseAct = p_c;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "ClickableObj.setBtnReleaseAct" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
}
